/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
// TODO inserire il meccanismo per disegnare il pulsante quando è selezionato
// TODO inserire il meccanimo di abilitazione e disabilitazione del pulsante
package customGuiControl;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Stack;
import javax.swing.JPanel;
import org.jdesktop.swingx.StackLayout;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import org.jdesktop.swingx.graphics.ShadowRenderer;

/**
 *
 * @author emilio
 */
public class roundedPanel extends JPanel {

    private int radius;
    private Color startColor;
    private Color endColor;
    private Float strokeWidth;
    private Color strokeColor;
    private BufferedImage shadow=null;
    private int offSetX=0;
    private int offSetY=0;
    private int shadowDimension=0;
    private Float gradientPercent=50f;
    private int endx=0;
    private int endy=0;
    private Dimension prevDim=null;
    protected  boolean Dirty=false;
    private Color shadowColor=null;
    private Float shadowOpacity=null;
    private String id=null;
    private Float proportinalShadowDim=null;


    protected DropShadowPanel dropShadowDesigner;

    public roundedPanel(int radius,Color startColor,
                        Color endColor,Float strokeWidth,Color strokeColor,
                        Float proportinalShadowDim, Float gradientPercent,
                        Color shadowColor, Float shadowOpacity,String id)
    {
        super();
        this.radius=radius;
        this.startColor=startColor;
        this.endColor=endColor;
        this.strokeWidth=strokeWidth;
        this.strokeColor=strokeColor;
        this.proportinalShadowDim=proportinalShadowDim;
        this.gradientPercent=gradientPercent;
        this.shadowColor=shadowColor;
        this.shadowOpacity=shadowOpacity;
        this.id=id;
        this.setOpaque(false);
    }
    public roundedPanel()
    {
        super();
    }
    @Override
    protected void paintComponent(Graphics g) {

        // setto la dimensione dell'ombra in modo proporzionale all'area dell'elemento.
        this.shadowDimension=new Float((new Float(this.getWidth()*this.getHeight())/this.proportinalShadowDim)).intValue();
        //System.out.println(new Float((new Float(this.getWidth()*this.getHeight())/this.proportinalShadowDim)));
        this.offSetX=this.shadowDimension+this.shadowDimension/3;
        this.offSetY=this.shadowDimension+this.shadowDimension/3;
        int x = this.getInsets().left;
        int y = this.getInsets().top;
        int w = getWidth()-this.offSetX;
        int h = getHeight()-this.offSetY;

       
        // verifico se la dimensione dell'elemento è effettivamente cambiata
        this.checkDirty();

        Graphics2D g2 = (Graphics2D) g.create();
        // creo una buffered image che rappresenta il pannello stesso
         BufferedImage fake_Image = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
         Graphics2D g2Image= fake_Image.createGraphics();
         g2Image.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        this.endy=(new Float((h-this.strokeWidth)*this.gradientPercent/100)).intValue();
        this.endx=this.strokeWidth.intValue();
        GradientPaint gradient1 =new GradientPaint(this.strokeWidth.intValue(),
                                                  this.strokeWidth.intValue(),
                                                  this.startColor,
                                                  this.endx,
                                                  this.endy,
                                                  this.endColor,false);
        g2Image.setPaint(gradient1);
        g2Image.fillRoundRect(x+this.strokeWidth.intValue(),
                         y+this.strokeWidth.intValue(),
                         w-(this.strokeWidth.intValue()*2),
                         h-(this.strokeWidth.intValue()*2),
                         this.radius, this.radius);
        g2Image.setStroke(new BasicStroke(this.strokeWidth.floatValue()));
        g2Image.setColor(this.strokeColor);
        g2Image.drawRoundRect(x+this.strokeWidth.intValue(),
                         y+this.strokeWidth.intValue(),
                         w-this.strokeWidth.intValue()*2-this.getInsets().right,
                         h-this.strokeWidth.intValue()*2-this.getInsets().bottom,
                         this.radius, this.radius);
        g2Image.dispose();
        
      if(this.dropShadowDesigner==null)
        {
            this.dropShadowDesigner= new DropShadowPanel(fake_Image);
            this.dropShadowDesigner.setShadowSize(this.shadowDimension);
            this.dropShadowDesigner.setShadowOpacity(this.shadowOpacity);
            this.dropShadowDesigner.setShadowColor(this.shadowColor);
            this.getParent().add(this.dropShadowDesigner,StackLayout.BOTTOM);
            //this.dropShadowDesigner.original=null;
        }
        else
        {
            if(this.Dirty)
            {
               this.redrawShadow(fake_Image);
            }
        }
        /*g2.drawImage(fake_Image, x , y , null);
        g2.dispose();*/

    }
    public void setGradient(Color start,Color end, Float percentPosition)
    {
        this.startColor=start;
        this.endColor=end;
        this.gradientPercent=percentPosition;
    }
    public ArrayList<Color> getGradient()
    {
        ArrayList<Color> colors=new ArrayList<Color>();
        colors.add(this.startColor);
        colors.add(this.endColor);
        return colors;
    }
    public Float getGradientPercent() {
        return gradientPercent;
    }

    public void setGradientPercent(Float gradientPercent) {
        this.gradientPercent = gradientPercent;
    }

    public Color getShadowColor() {
        return shadowColor;
    }

    public void setShadowColor(Color shadowColor) {
        this.shadowColor = shadowColor;
    }

    public Color getStrokeColor() {
        return strokeColor;
    }

    public void setStrokeColor(Color strokeColor) {
        this.strokeColor = strokeColor;
    }

    public Float getStrokeWidth() {
        return strokeWidth;
    }

    public void setStrokeWidth(Float strokeWidth) {
        this.strokeWidth = strokeWidth;
    }
    public void dirtyRepaint()
    {
        this.Dirty=true;
        this.repaint();
    }
    public void redrawShadow(BufferedImage fake_Image)
    {
        this.Dirty=false;
        this.dropShadowDesigner.setShadowSize(this.shadowDimension);
        this.dropShadowDesigner.setShadowOpacity(this.shadowOpacity);
        this.dropShadowDesigner.setShadowColor(this.shadowColor);
        this.dropShadowDesigner.refreshShadow(fake_Image);
        this.dropShadowDesigner.repaint();
    }
    public boolean checkDirty(){
        if(this.prevDim==null)
        {
            this.prevDim=new Dimension(this.getWidth(), this.getHeight());
        }else
        {
            if(this.prevDim.height!=this.getHeight()||this.prevDim.getWidth()!=this.getWidth())
            {
                this.Dirty = true;
                this.prevDim.height=this.getHeight();
                this.prevDim.width=this.getWidth();
                return true;
            }


        }
        this.prevDim.height=this.getHeight();
        this.prevDim.width=this.getWidth();
        return false;

    }

    public Dimension getPrevDim() {
        return prevDim;
    }

}
